package com.ddwl.admin.notifier;

import com.alibaba.fastjson.JSON;
import com.ddwl.admin.bo.DingTalkBo;
import com.ddwl.admin.feign.DingTalkApi;
import com.ddwl.admin.vo.DingTalkRestVo;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.util.Date;


@Slf4j
@Component
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "prod")
public class CustomNotifier extends AbstractEventNotifier {

    @Value("${dingtalk.exception_robot.access_token}")
    private String accessToken;

    private final DingTalkApi dingTalkApi;

    public CustomNotifier(InstanceRepository repository, DingTalkApi dingTalkApi) {
        super(repository);
        this.dingTalkApi = dingTalkApi;
    }

    /**
     * 消息模板
     */
    private static final String template = "#### %s%s(%s) [广播][广播][广播]\n ---\n - 实例ID %s\n - 服务地址 %s\n - %s";


    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            if (event instanceof InstanceStatusChangedEvent) {
                log.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());


                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
                switch (status) {
                    // 健康检查没通过
                    case "DOWN":
                        log.info("发送 健康检查没通过 的通知！");
                        this.sendMessage("健康检查没通过", instance.getRegistration().getName(), event.getInstance().toString(), ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), instance.getRegistration().getServiceUrl());
                        break;
                    // 服务离线
                    case "OFFLINE":
                        log.info("发送 服务离线 的通知！");
                        this.sendMessage("服务离线", instance.getRegistration().getName(), event.getInstance().toString(), ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), instance.getRegistration().getServiceUrl());
                        break;
                    //服务上线
                    case "UP":
                        log.info("发送 服务上线 的通知！");
                        this.sendMessage("服务上线", instance.getRegistration().getName(), event.getInstance().toString(), ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), instance.getRegistration().getServiceUrl());
                        break;
                    // 服务未知异常
                    case "UNKNOWN":
                        log.info("发送 服务未知异常 的通知！");
                        this.sendMessage("服务未知异常", instance.getRegistration().getName(), event.getInstance().toString(), ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), instance.getRegistration().getServiceUrl());
                        break;
                    default:
                        break;
                }
            } else {
                log.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(), event.getType());
            }
        });
    }

    /**
     * 发送消息
     */
    private void sendMessage(String title, String serviceName, String instantId, String statusInfo, String serverUrl) {
        DingTalkBo msg = new DingTalkBo();
        DingTalkBo.Text actionCard = msg.new Text();
        actionCard.setTitle(title);
        actionCard.setText(String.format(template, serviceName, title, statusInfo, instantId, serverUrl, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
        actionCard.setSingleTitle("立即查看");
        actionCard.setSingleURL("http://monit.zjddwl.com");
        msg.setMsgtype("actionCard");
        msg.setActionCard(actionCard);
        DingTalkRestVo resp = dingTalkApi.send(accessToken, msg);
        log.info("DingTalk exception resp: {}", JSON.toJSONString(resp));
    }
}